home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
366_01
/
ue311c1.arc
/
BUFFER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-10
|
14KB
|
591 lines
/* BUFFER.C: buffer mgmt. routines
MicroEMACS 3.10
* Buffer management.
* Some of the functions are internal,
* and some are actually attached to user
* keys. Like everyone else, they set hints
* for the display system.
*/
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
/*
* Attach a buffer to a window. The
* values of dot and mark come from the buffer
* if the use count is 0. Otherwise, they come
* from some other window.
*/
PASCAL NEAR usebuffer(f, n)
int f,n; /* prefix flag and argument */
{
register BUFFER *bp; /* temporary buffer pointer */
/* get the buffer name to switch to */
bp = getdefb();
bp = getcbuf(TEXT24, bp ? bp->b_bname : mainbuf, TRUE);
/* "Use buffer" */
if (!bp)
return(ABORT);
/* make it invisable if there is an argument */
if (f == TRUE)
bp->b_flag |= BFINVS;
/* switch to it in any case */
return(swbuffer(bp));
}
PASCAL NEAR nextbuffer(f, n) /* switch to the next buffer in the buffer list */
int f, n; /* default flag, numeric argument */
{
register BUFFER *bp; /* current eligable buffer */
register int status;
/* make sure the arg is legit */
if (f == FALSE)
n = 1;
if (n < 1)
return(FALSE);
/* cycle thru buffers until n runs out */
while (n-- > 0) {
bp = getdefb();
if (bp == NULL)
return(FALSE);
status = swbuffer(bp);
if (status != TRUE)
return(status);
}
return(status);
}
PASCAL NEAR swbuffer(bp) /* make buffer BP current */
BUFFER *bp;
{
register WINDOW *wp;
SCREEN *scrp; /* screen to fix pointers in */
register int cmark; /* current mark */
/* let a user macro get hold of things...if he wants */
execkey(&exbhook, FALSE, 1);
if (--curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
for (cmark = 0; cmark < NMARKS; cmark++) {
curbp->b_markp[cmark] = curwp->w_markp[cmark];
curbp->b_marko[cmark] = curwp->w_marko[cmark];
}
curbp->b_fcol = curwp->w_fcol;
}
curbp = bp; /* Switch. */
if (curbp->b_active != TRUE) { /* buffer not active yet*/
/* read it in and activate it */
readin(curbp->b_fname, ((curbp->b_mode&MDVIEW) == 0));
curbp->b_dotp = lforw(curbp->b_linep);
curbp->b_doto = 0;
curbp->b_active = TRUE;
}
curwp->w_bufp = bp;
curwp->w_linep = bp->b_linep; /* For macros, ignored. */
curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty. */
if (bp->b_nwnd++ == 0) { /* First use. */
curwp->w_dotp = bp->b_dotp;
curwp->w_doto = bp->b_doto;
for (cmark = 0; cmark < NMARKS; cmark++) {
curwp->w_markp[cmark] = bp->b_markp[cmark];
curwp->w_marko[cmark] = bp->b_marko[cmark];
}
curwp->w_fcol = bp->b_fcol;
} else {
/* in all screens.... */
scrp = first_screen;
while (scrp) {
wp = scrp->s_first_window;
while (wp != NULL) {
if (wp!=curwp && wp->w_bufp==bp) {
curwp->w_dotp = wp->w_dotp;
curwp->w_doto = wp->w_doto;
for (cmark = 0; cmark < NMARKS; cmark++) {
curwp->w_markp[cmark] = wp->w_markp[cmark];
curwp->w_marko[cmark] = wp->w_marko[cmark];
}
curwp->w_fcol = wp->w_fcol;
break;
}
/* next window */
wp = wp->w_wndp;
}
/* next screen! */
scrp = scrp->s_next_screen;
}
}
/* let a user macro get hold of things...if he wants */
execkey(&bufhook, FALSE, 1);
return(TRUE);
}
/*
* Dispose of a buffer, by name.
* Ask for the name. Look it up (don't get too
* upset if it isn't there at all!). Get quite upset
* if the buffer is being displayed. Clear the buffer (ask
* if the buffer has been changed). Then free the header
* line and the buffer header. Bound to "C-X K".
*/
PASCAL NEAR killbuffer(f, n)
int f,n; /* prefix flag and argument */
{
register BUFFER *bp; /* ptr to buffer to dump */
/* get the buffer name to kill */
bp = getdefb();
bp = getcbuf(TEXT26, bp ? bp->b_bname : mainbuf, TRUE);
/* "Kill buffer" */
if (bp == NULL)
return(ABORT);
return(zotbuf(bp));
}
/* Allow the user to pop up a buffer, like we do.... */
PASCAL NEAR popbuffer(f, n)
int f, n; /* default and numeric arguments */
{
register BUFFER *bp; /* ptr to buffer to dump */
/* get the buffer name to pop */
bp = getdefb();
bp = getcbuf(TEXT27, bp ? bp->b_bname : mainbuf, TRUE);
/* "Pop buffer" */
if (bp == NULL)
return(ABORT);
return(pop(bp));
}
BUFFER *PASCAL NEAR getdefb() /* get the default buffer for a use or kill */
{
BUFFER *bp; /* default buffer */
/* Find the next buffer, which will be the default */
bp = curbp->b_bufp;
/* cycle through the buffers to find an eligable one */
while (bp == NULL || bp->b_flag & BFINVS) {
if (bp == NULL)
bp = bheadp;
else
bp = bp->b_bufp;
/* don't get caught in an infinite loop! */
if (bp == curbp) {
bp = NULL;
break;
}
}
return(bp);
}
PASCAL NEAR zotbuf(bp) /* kill the buffer pointed to by bp */
register BUFFER *bp;
{
register BUFFER *bp1;
register BUFFER *bp2;
register int s;
/* we can not kill a displayed buffer */
if (bp->b_nwnd != 0) {
mlwrite(TEXT28);
/* "Buffer is being displayed" */
return(FALSE);
}
/* we can not kill an executing buffer */
if (bp->b_exec != 0) {
mlwrite(TEXT226);
/* "%%Can not delete an executing buffer" */
return(FALSE);
}
if ((s=bclear(bp)) != TRUE) /* Blow text away. */
return(s);
free((char *) bp->b_linep); /* Release header line. */
bp1 = NULL; /* Find the header. */
bp2 = bheadp;
while (bp2 != bp) {
bp1 = bp2;
bp2 = bp2->b_bufp;
}
bp2 = bp2->b_bufp; /* Next one in chain. */
if (bp1 == NULL) /* Unlink it. */
bheadp = bp2;
else
bp1->b_bufp = bp2;
free((char *) bp); /* Release buffer block */
return(TRUE);
}
PASCAL NEAR namebuffer(f,n) /* Rename the current buffer */
int f, n; /* default Flag & Numeric arg */
{
register BUFFER *bp; /* pointer to scan through all buffers */
char bufn[NBUFN]; /* buffer to hold buffer name */
/* prompt for and get the new buffer name */
ask: if (mlreply(TEXT29, bufn, NBUFN) != TRUE)
/* "Change buffer name to: " */
return(FALSE);
/* and check for duplicates */
bp = bheadp;
while (bp != NULL) {
if (bp != curbp) {
/* if the names the same */
if (strcmp(bufn, bp->b_bname) == 0)
goto ask; /* try again */
}
bp = bp->b_bufp; /* onward */
}
strcpy(curbp->b_bname, bufn); /* copy buffer name to structure */
upmode(); /* make all mode lines replot */
mlerase();
return(TRUE);
}
/* Build and popup a buffer containing the list of all buffers.
Bound to "C-X C-B". A numeric argument forces it to list
invisable buffers as well.
*/
PASCAL NEAR listbuffers(f, n)
int f,n; /* prefix flag and argument */
{
register int status; /* stutus return */
if ((status = makelist(f)) != TRUE)
return(status);
return(wpopup(blistp));
}
/*
* This routine rebuilds the
* text in the special secret buffer
* that holds the buffer list. It is called
* by the list buffers command. Return TRUE
* if everything works. Return FALSE if there
* is an error (if there is no memory). Iflag
* indecates weather to list hidden buffers.
*/
PASCAL NEAR makelist(iflag)
int iflag; /* list hidden buffer flag */
{
register char *cp1;
register char *cp2;
register int c;
register BUFFER *bp;
register LINE *lp;
register int s;
register int i;
long nbytes; /* # of bytes in current buffer */
char b[7+1];
char line[128];
blistp->b_flag &= ~BFCHG; /* Don't complain! */
if ((s=bclear(blistp)) != TRUE) /* Blow old text away */
return(s);
strcpy(blistp->b_fname, "");
if (addline(blistp, TEXT30) == FALSE
/* "ACT Modes Size Buffer File" */
|| addline(blistp, "--- --------- ------- --------------- ----") == FALSE)
return(FALSE);
bp = bheadp; /* For all buffers */
/* build line to report global mode settings */
cp1 = &line[0];
*cp1++ = ' '